package com.ftw.commons.utils.inputfilter

import android.text.InputFilter
import android.text.Spanned


class EmojiFilter : InputFilter {


    init {
        filterSet = HashSet()
        scopeSet = HashSet()
        // See http://apps.timwhitlock.info/emoji/tables/unicode

        // 1. Emoticons ( 1F601 - 1F64F )
        // See http://apps.timwhitlock.info/emoji/tables/unicode
// 1. Emoticons ( 1F601 - 1F64F )
        addUnicodeRangeToSet(filterSet, 0x1F601, 0X1F64F)

        // 2. Dingbats ( 2702 - 27B0 )
        // 2. Dingbats ( 2702 - 27B0 )
        addUnicodeRangeToSet(filterSet, 0x2702, 0X27B0)

        // 3. Transport and map symbols ( 1F680 - 1F6C0 )
        // 3. Transport and map symbols ( 1F680 - 1F6C0 )
        addUnicodeRangeToSet(filterSet, 0X1F680, 0X1F6C0)

        // 4. Enclosed characters ( 24C2 - 1F251 )
        // 4. Enclosed characters ( 24C2 - 1F251 )
        addUnicodeRangeToSet(filterSet, 0X24C2)
        addUnicodeRangeToSet(filterSet, 0X1F170, 0X1F251)

        // 6a. Additional emoticons ( 1F600 - 1F636 )
        // 6a. Additional emoticons ( 1F600 - 1F636 )
        addUnicodeRangeToSet(filterSet, 0X1F600, 0X1F636)

        // 6b. Additional transport and map symbols ( 1F681 - 1F6C5 )
        // 6b. Additional transport and map symbols ( 1F681 - 1F6C5 )
        addUnicodeRangeToSet(filterSet, 0X1F681, 0X1F6C5)

        // 6c. Other additional symbols ( 1F30D - 1F567 )
        // 6c. Other additional symbols ( 1F30D - 1F567 )
        addUnicodeRangeToSet(filterSet, 0X1F30D, 0X1F567)

        // 5. Uncategorized
        // 5. Uncategorized
        addUnicodeRangeToSet(filterSet, 0X1F004)
        addUnicodeRangeToSet(filterSet, 0X1F0CF)
        // 与6c. Other additional symbols ( 1F30D - 1F567 )重复
        // 去掉重复部分虽然不去掉HashSet也不会重复，原范围（0X1F300 - 0X1F5FF）
        // 与6c. Other additional symbols ( 1F30D - 1F567 )重复
// 去掉重复部分虽然不去掉HashSet也不会重复，原范围（0X1F300 - 0X1F5FF）
        addUnicodeRangeToSet(filterSet, 0X1F300, 0X1F30D)
        addUnicodeRangeToSet(filterSet, 0X1F5FB, 0X1F5FF)
        addUnicodeRangeToSet(filterSet, 0X00A9)
        addUnicodeRangeToSet(filterSet, 0X00AE)
        addUnicodeRangeToSet(filterSet, 0X0023)
        //阿拉伯数字0-9，配合0X20E3使用
        //addUnicodeRangeToSet(filterSet, 0X0030, 0X0039);
        // 过滤掉203C开始后的2XXX 段落
        //addUnicodeRangeToSet(filterSet, 0X203C, 0X24C2);
        //阿拉伯数字0-9，配合0X20E3使用
//addUnicodeRangeToSet(filterSet, 0X0030, 0X0039);
// 过滤掉203C开始后的2XXX 段落
//addUnicodeRangeToSet(filterSet, 0X203C, 0X24C2);
        addUnicodeRangeToSet(filterSet, 0X203C)
        addUnicodeRangeToSet(filterSet, 0X2049)
        //严格验证的话需要判断前面是否是数字
        //Android上显示和数字分开可以不判断
        //严格验证的话需要判断前面是否是数字
//Android上显示和数字分开可以不判断
        addUnicodeRangeToSet(filterSet, 0X20E3)
        addUnicodeRangeToSet(filterSet, 0X2122)
        addUnicodeRangeToSet(filterSet, 0X2139)
        addUnicodeRangeToSet(filterSet, 0X2194, 0X2199)
        addUnicodeRangeToSet(filterSet, 0X21A9, 0X21AA)
        addUnicodeRangeToSet(filterSet, 0X231A, 0X231B)
        addUnicodeRangeToSet(filterSet, 0X23E9, 0X23EC)
        addUnicodeRangeToSet(filterSet, 0X23F0)
        addUnicodeRangeToSet(filterSet, 0X23F3)
        addUnicodeRangeToSet(filterSet, 0X25AA, 0X25AB)
        addUnicodeRangeToSet(filterSet, 0X25FB, 0X25FE)
        //TODO： 26XX 太杂全部过滤
        //TODO： 26XX 太杂全部过滤
        addUnicodeRangeToSet(filterSet, 0X2600, 0X26FE)
        addUnicodeRangeToSet(filterSet, 0X2934, 0X2935)
        addUnicodeRangeToSet(filterSet, 0X2B05, 0X2B07)
        addUnicodeRangeToSet(filterSet, 0X2B1B, 0X2B1C)
        addUnicodeRangeToSet(filterSet, 0X2B50)
        addUnicodeRangeToSet(filterSet, 0X2B55)
        addUnicodeRangeToSet(filterSet, 0X3030)
        addUnicodeRangeToSet(filterSet, 0X303D)
        addUnicodeRangeToSet(filterSet, 0X3297)
        addUnicodeRangeToSet(filterSet, 0X3299)
    }

    companion object {

        private var filterSet: HashSet<String>? = null
        private var scopeSet: HashSet<Scope>? = null


        fun addUnicodeRangeToSet(
            set: Set<String?>?,
            code: Int
        ) {
            if (set == null) {
                return
            }
            filterSet?.add(String(intArrayOf(code), 0, 1))
        }


        fun addUnicodeRangeToSet(
            set: Set<String?>?,
            start: Int,
            end: Int
        ) {
            if (set == null) {
                return
            }
            if (start > end) {
                return
            }
            for (i in start..end) {
                filterSet?.add(String(intArrayOf(i), 0, 1))
            }
        }

    }

    override fun filter(
        source: CharSequence?,
        p1: Int,
        p2: Int,
        p3: Spanned?,
        p4: Int,
        p5: Int
    ): CharSequence? {
        return if (filterSet!!.contains(source.toString())) {
            ""
        } else source
    }

}

class Scope {
    var start = 0
    var end = 0
    override fun equals(other: Any?): Boolean {
        if (other is Scope) {
            val scope = other
            if (scope.start == start && scope.end == end) {
                return true
            }
        }
        return super.equals(other)
    }

    override fun hashCode(): Int {
        var result = start
        result = 31 * result + end
        return result
    }
}
